import 'dart:typed_data';

import 'package:flutter/foundation.dart';

// 工具类
class Utils {
  // 判断字符串是否为纯数字
  static bool isNumeric(String text) {
    return RegExp(r'^\d+$').hasMatch(text);
  }

  // 判断字符串是否为非中文
  static bool isNotChinese(String text) {
    return !RegExp(r'[\u4e00-\u9fa5]').hasMatch(text);
  }

  // 将 Uint8List 转换int
  static int uint8List2Int(Uint8List bytes, {Endian endian = Endian.big}) {
    var result = 0;
    if (endian == Endian.big) {
      for (var i = 0; i < bytes.length; i++) {
        result = (result << 8) | bytes[i];
      }
    } else {
      for (var i = bytes.length - 1; i >= 0; i--) {
        result = (result << 8) | bytes[i];
      }
    }
    return result;
  }

  // 将 Uint8List 转换为文本
  static String uint8List2Text(Uint8List uint8List) {
    try {
      return String.fromCharCodes(uint8List).replaceAll('\u0000', '');
    } catch (e) {
      // Fallback to hex string conversion if UTF-8 decoding fails
      return hexString2Text(uint8List2HexString(uint8List));
    }
  }

  // 将 Uint8List 转换为字符串
  static String uint8List2HexString(Uint8List uint8List) {
    return uint8List
        .map((byte) => byte.toRadixString(16).padLeft(2, '0').toUpperCase())
        .join();
  }

  // 将hex字符串转Uint8List
  static Uint8List hexString2Uint8List(String hexString) {
    // 去除可能的空白字符
    hexString = hexString.replaceAll(RegExp(r'\s'), '');

    // 将字符串分割为每两个字符一组
    List<String> hexPairs = [];
    for (int i = 0; i < hexString.length; i += 2) {
      hexPairs.add(hexString.substring(i, i + 2));
    }

    // 将每对十六进制字符转换为字节
    Uint8List result = Uint8List(hexPairs.length);
    for (int i = 0; i < hexPairs.length; i++) {
      result[i] = int.parse(hexPairs[i], radix: 16);
    }

    return result;
  }

  // 将字符串转文本
  static String hexString2Text(String hexString) {
    // 去除可能的空白字符
    hexString = hexString.replaceAll(RegExp(r'\s'), '');

    // 将字符串分割为每两个字符一组
    List<String> hexPairs = [];
    for (int i = 0; i < hexString.length; i += 2) {
      hexPairs.add(hexString.substring(i, i + 2));
    }

    // 将每对十六进制字符转换为 ASCII 字符
    String result = '';
    for (String hexPair in hexPairs) {
      int charCode = int.parse(hexPair, radix: 16);
      if (charCode == 0) break; // 忽略空字符
      result += String.fromCharCode(charCode);
    }

    return result;
  }

  // 计算dataInt
  static int computeDataIntVal(Uint8List msgData) {
    var val = 0;
    for (var i = 0; i < msgData.length; i++) {
      val += msgData[i];
    }
    return val;
  }

  // int 转换为 Uint8List
  static Uint8List int2Uint8List(int number, {Endian endian = Endian.big}) {
    // 计算需要的字节数
    int byteCount = (number.bitLength + 7) ~/ 8;

    // 创建 ByteData
    ByteData byteData = ByteData(byteCount);

    // 将整数写入 ByteData
    for (int i = 0; i < byteCount; i++) {
      int offset = (byteCount - 1 - i) * 8; // 大端序
      byteData.setUint8(i, (number >> offset) & 0xFF);
    }

    // 转换为 Uint8List
    return byteData.buffer.asUint8List();
  }

  // 将整数（int）转换为 8 字节（64 位）的字节数组（Uint8List）
  static Uint8List intTo8Bytes(int value) {
    final byteData = ByteData(8); // 8 字节 = 64 位
    byteData.setUint64(0, value, Endian.little); // 小端序存储
    return byteData.buffer.asUint8List();
  }

  // 每遇到一个 0xAA 或 0xA5 则在其前方插入一个 0xA5，前两个字节除外
  static List<int> insertBeforTargets(
    List<int> input, {
    List<int> targets = const [0xAA, 0xA5],
    int insert = 0xA5,
  }) {
    // 创建一个新的列表来存储处理后的字节
    List<int> output = [];
    // 遍历输入字节数组
    for (int i = 0; i < input.length; i++) {
      // 检查当前字节是否为 0xAA 或 0xA5
      if (targets.contains(input[i])) {
        // 在 0xAA 或 0xA5 前插入 0xA5
        output.add(insert);
      }
      // 添加当前字节到输出列表
      output.add(input[i]);
    }
    return output;
  }

  // 如果发现某个字节是 insert（默认为 0xA5），并且它后面的字节是 targets 列表中的目标字节之一（默认为 [0xAA, 0xA5]），则移除这个 insert 字节。
  static List<int> removeInsertedBytes(
    List<int> input, {
    int insert = 0xA5,
  }) {
    // 创建一个新的列表来存储处理后的字节
    List<int> output = [];
    // 遍历输入字节数组
    bool isSkipped = false;
    for (int i = 0; i < input.length; i++) {
      // 为转义符号，且不是最后一个字节，且下一个字节是目标字节之一
      if (isSkipped) {
        isSkipped = false;
      } else {
        if (insert == input[i]) {
          isSkipped = true;
          continue;
        }
      }

      // 添加当前字节到输出列表
      output.add(input[i]);
    }
    return output;
  }

  /// CRC32 计算函数
  ///
  /// [data] - 要计算的数据字节列表
  ///
  /// 返回计算得到的CRC32值
  /* demo
    final testData = 'Hello World'.codeUnits; // 转换为字节列表
    final crcValue = calCrc32(testData);
    print('CRC32: 0x${crcValue.toRadixString(16).padLeft(8, '0')}');
  */
  static int calCrc32(Uint8List data) {
    int crc32 = 0xFFFFFFFF;

    for (int i = 0; i < data.length; i++) {
      crc32 = (crc32 >> 8) ^ crc32Table[(crc32 ^ data[i]) & 0xFF];
    }

    return crc32 ^ 0xFFFFFFFF;
  }

  // 从 ByteData 中直接提取 4 字节为 Uint8List，支持大小端序
  static Uint8List uint32ToUint8ListDirect(ByteData byteData, int offset,
      [Endian endian = Endian.little]) {
    // 直接从原始buffer中提取4个字节
    final result = Uint8List(4);
    for (int i = 0; i < 4; i++) {
      result[i] = byteData.getUint8(offset + i);
    }

    // 如果需要调整字节序
    if (endian == Endian.big) {
      // 大端序已经是正确的顺序
      return result;
    } else {
      // 小端序需要反转
      return Uint8List.fromList(result.reversed.toList());
    }
  }
}

// crc32校验表
const crc32Table = [
  0x00000000,
  0x77073096,
  0xEE0E612C,
  0x990951BA,
  0x076DC419,
  0x706AF48F,
  0xE963A535,
  0x9E6495A3,
  0x0EDB8832,
  0x79DCB8A4,
  0xE0D5E91E,
  0x97D2D988,
  0x09B64C2B,
  0x7EB17CBD,
  0xE7B82D07,
  0x90BF1D91,
  0x1DB71064,
  0x6AB020F2,
  0xF3B97148,
  0x84BE41DE,
  0x1ADAD47D,
  0x6DDDE4EB,
  0xF4D4B551,
  0x83D385C7,
  0x136C9856,
  0x646BA8C0,
  0xFD62F97A,
  0x8A65C9EC,
  0x14015C4F,
  0x63066CD9,
  0xFA0F3D63,
  0x8D080DF5,
  0x3B6E20C8,
  0x4C69105E,
  0xD56041E4,
  0xA2677172,
  0x3C03E4D1,
  0x4B04D447,
  0xD20D85FD,
  0xA50AB56B,
  0x35B5A8FA,
  0x42B2986C,
  0xDBBBC9D6,
  0xACBCF940,
  0x32D86CE3,
  0x45DF5C75,
  0xDCD60DCF,
  0xABD13D59,
  0x26D930AC,
  0x51DE003A,
  0xC8D75180,
  0xBFD06116,
  0x21B4F4B5,
  0x56B3C423,
  0xCFBA9599,
  0xB8BDA50F,
  0x2802B89E,
  0x5F058808,
  0xC60CD9B2,
  0xB10BE924,
  0x2F6F7C87,
  0x58684C11,
  0xC1611DAB,
  0xB6662D3D,
  0x76DC4190,
  0x01DB7106,
  0x98D220BC,
  0xEFD5102A,
  0x71B18589,
  0x06B6B51F,
  0x9FBFE4A5,
  0xE8B8D433,
  0x7807C9A2,
  0x0F00F934,
  0x9609A88E,
  0xE10E9818,
  0x7F6A0DBB,
  0x086D3D2D,
  0x91646C97,
  0xE6635C01,
  0x6B6B51F4,
  0x1C6C6162,
  0x856530D8,
  0xF262004E,
  0x6C0695ED,
  0x1B01A57B,
  0x8208F4C1,
  0xF50FC457,
  0x65B0D9C6,
  0x12B7E950,
  0x8BBEB8EA,
  0xFCB9887C,
  0x62DD1DDF,
  0x15DA2D49,
  0x8CD37CF3,
  0xFBD44C65,
  0x4DB26158,
  0x3AB551CE,
  0xA3BC0074,
  0xD4BB30E2,
  0x4ADFA541,
  0x3DD895D7,
  0xA4D1C46D,
  0xD3D6F4FB,
  0x4369E96A,
  0x346ED9FC,
  0xAD678846,
  0xDA60B8D0,
  0x44042D73,
  0x33031DE5,
  0xAA0A4C5F,
  0xDD0D7CC9,
  0x5005713C,
  0x270241AA,
  0xBE0B1010,
  0xC90C2086,
  0x5768B525,
  0x206F85B3,
  0xB966D409,
  0xCE61E49F,
  0x5EDEF90E,
  0x29D9C998,
  0xB0D09822,
  0xC7D7A8B4,
  0x59B33D17,
  0x2EB40D81,
  0xB7BD5C3B,
  0xC0BA6CAD,
  0xEDB88320,
  0x9ABFB3B6,
  0x03B6E20C,
  0x74B1D29A,
  0xEAD54739,
  0x9DD277AF,
  0x04DB2615,
  0x73DC1683,
  0xE3630B12,
  0x94643B84,
  0x0D6D6A3E,
  0x7A6A5AA8,
  0xE40ECF0B,
  0x9309FF9D,
  0x0A00AE27,
  0x7D079EB1,
  0xF00F9344,
  0x8708A3D2,
  0x1E01F268,
  0x6906C2FE,
  0xF762575D,
  0x806567CB,
  0x196C3671,
  0x6E6B06E7,
  0xFED41B76,
  0x89D32BE0,
  0x10DA7A5A,
  0x67DD4ACC,
  0xF9B9DF6F,
  0x8EBEEFF9,
  0x17B7BE43,
  0x60B08ED5,
  0xD6D6A3E8,
  0xA1D1937E,
  0x38D8C2C4,
  0x4FDFF252,
  0xD1BB67F1,
  0xA6BC5767,
  0x3FB506DD,
  0x48B2364B,
  0xD80D2BDA,
  0xAF0A1B4C,
  0x36034AF6,
  0x41047A60,
  0xDF60EFC3,
  0xA867DF55,
  0x316E8EEF,
  0x4669BE79,
  0xCB61B38C,
  0xBC66831A,
  0x256FD2A0,
  0x5268E236,
  0xCC0C7795,
  0xBB0B4703,
  0x220216B9,
  0x5505262F,
  0xC5BA3BBE,
  0xB2BD0B28,
  0x2BB45A92,
  0x5CB36A04,
  0xC2D7FFA7,
  0xB5D0CF31,
  0x2CD99E8B,
  0x5BDEAE1D,
  0x9B64C2B0,
  0xEC63F226,
  0x756AA39C,
  0x026D930A,
  0x9C0906A9,
  0xEB0E363F,
  0x72076785,
  0x05005713,
  0x95BF4A82,
  0xE2B87A14,
  0x7BB12BAE,
  0x0CB61B38,
  0x92D28E9B,
  0xE5D5BE0D,
  0x7CDCEFB7,
  0x0BDBDF21,
  0x86D3D2D4,
  0xF1D4E242,
  0x68DDB3F8,
  0x1FDA836E,
  0x81BE16CD,
  0xF6B9265B,
  0x6FB077E1,
  0x18B74777,
  0x88085AE6,
  0xFF0F6A70,
  0x66063BCA,
  0x11010B5C,
  0x8F659EFF,
  0xF862AE69,
  0x616BFFD3,
  0x166CCF45,
  0xA00AE278,
  0xD70DD2EE,
  0x4E048354,
  0x3903B3C2,
  0xA7672661,
  0xD06016F7,
  0x4969474D,
  0x3E6E77DB,
  0xAED16A4A,
  0xD9D65ADC,
  0x40DF0B66,
  0x37D83BF0,
  0xA9BCAE53,
  0xDEBB9EC5,
  0x47B2CF7F,
  0x30B5FFE9,
  0xBDBDF21C,
  0xCABAC28A,
  0x53B39330,
  0x24B4A3A6,
  0xBAD03605,
  0xCDD70693,
  0x54DE5729,
  0x23D967BF,
  0xB3667A2E,
  0xC4614AB8,
  0x5D681B02,
  0x2A6F2B94,
  0xB40BBE37,
  0xC30C8EA1,
  0x5A05DF1B,
  0x2D02EF8D
];
